home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Internet / WWW / httpd_1.5.export / support / htpasswd.c < prev    next >
C/C++ Source or Header  |  1995-11-09  |  4KB  |  193 lines

  1. /*
  2.  * htpasswd.c: simple program for manipulating password file for NCSA httpd
  3.  * 
  4.  * Rob McCool
  5.  */
  6.  
  7. #include "config.h"
  8. #include "portability.h"
  9.  
  10. #include <sys/types.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <sys/signal.h>
  14. #include <stdlib.h>
  15. #include <time.h>
  16. #ifdef NEED_CRYPT_H
  17. #include <crypt.h>
  18. #endif /* NEED_CRYPT_H */
  19.  
  20. #define LF 10
  21. #define CR 13
  22.  
  23. #define MAX_STRING_LEN 256
  24.  
  25. char *tn;
  26.  
  27. char *strd(char *s) {
  28.     char *d;
  29.  
  30.     d=(char *)malloc(strlen(s) + 1);
  31.     strcpy(d,s);
  32.     return(d);
  33. }
  34.  
  35. void getword(char *word, char *line, char stop) {
  36.     int x = 0,y;
  37.  
  38.     for(x=0;((line[x]) && (line[x] != stop));x++)
  39.         word[x] = line[x];
  40.  
  41.     word[x] = '\0';
  42.     if(line[x]) ++x;
  43.     y=0;
  44.  
  45.     while(line[y++] = line[x++]);
  46. }
  47.  
  48. int getline(char *s, int n, FILE *f) {
  49.     register int i=0;
  50.  
  51.     while(1) {
  52.         s[i] = (char)fgetc(f);
  53.  
  54.         if(s[i] == CR)
  55.             s[i] = fgetc(f);
  56.  
  57.         if((s[i] == 0x4) || (s[i] == LF) || (i == (n-1))) {
  58.             s[i] = '\0';
  59.             return (feof(f) ? 1 : 0);
  60.         }
  61.         ++i;
  62.     }
  63. }
  64.  
  65. void putline(FILE *f,char *l) {
  66.     int x;
  67.  
  68.     for(x=0;l[x];x++) fputc(l[x],f);
  69.     fputc('\n',f);
  70. }
  71.  
  72.  
  73. /* From local_passwd.c (C) Regents of Univ. of California blah blah */
  74. static unsigned char itoa64[] =         /* 0 ... 63 => ascii - 64 */
  75.         "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  76.  
  77. to64(s, v, n)
  78.   register char *s;
  79.   register long v;
  80.   register int n;
  81. {
  82.     while (--n >= 0) {
  83.         *s++ = itoa64[v&0x3f];
  84.         v >>= 6;
  85.     }
  86. }
  87.  
  88. #ifdef HEAD_CRYPT
  89. char *crypt(char *pw, char *salt); /* why aren't these prototyped in include */
  90. #endif /* HEAD_CRYPT */
  91.  
  92. #ifdef HEAD_GETPASS
  93. char *getpass(char *prompt);
  94. #endif /* HEAD_GETPASS */
  95.  
  96. void add_password(char *user, FILE *f) {
  97.     char *pw, *cpw, salt[3];
  98.  
  99.     pw = strd(getpass("New password:"));
  100.     if(strcmp(pw,getpass("Re-type new password:"))) {
  101.         fprintf(stderr,"They don't match, sorry.\n");
  102.         if(tn)
  103.             unlink(tn);
  104.         exit(1);
  105.     }
  106.     (void)srand((int)time((time_t *)NULL));
  107.     to64(&salt[0],rand(),2);
  108.     cpw = crypt(pw,salt);
  109.     free(pw);
  110.     fprintf(f,"%s:%s\n",user,cpw);
  111. }
  112.  
  113. void usage() {
  114.     fprintf(stderr,"Usage: htpasswd [-c] passwordfile username\n");
  115.     fprintf(stderr,"The -c flag creates a new file.\n");
  116.     exit(1);
  117. }
  118.  
  119. void interrupted() {
  120.     fprintf(stderr,"Interrupted.\n");
  121.     if(tn) unlink(tn);
  122.     exit(1);
  123. }
  124.  
  125. main(int argc, char *argv[]) {
  126.     FILE *tfp,*f;
  127.     char user[MAX_STRING_LEN];
  128.     char line[MAX_STRING_LEN];
  129.     char l[MAX_STRING_LEN];
  130.     char w[MAX_STRING_LEN];
  131.     char command[MAX_STRING_LEN];
  132.     int found;
  133.  
  134.     tn = NULL;
  135.     signal(SIGINT,(void (*)())interrupted);
  136.     if(argc == 4) {
  137.         if(strcmp(argv[1],"-c"))
  138.             usage();
  139.         if(!(tfp = fopen(argv[2],"w"))) {
  140.             fprintf(stderr,"Could not open passwd file %s for writing.\n",
  141.                     argv[2]);
  142.             perror("fopen");
  143.             exit(1);
  144.         }
  145.         printf("Adding password for %s.\n",argv[3]);
  146.         add_password(argv[3],tfp);
  147.         fclose(tfp);
  148.         exit(0);
  149.     } else if(argc != 3) usage();
  150.  
  151.     tn = tmpnam(NULL);
  152.     if(!(tfp = fopen(tn,"w"))) {
  153.         fprintf(stderr,"Could not open temp file.\n");
  154.         exit(1);
  155.     }
  156.  
  157.     if(!(f = fopen(argv[1],"r"))) {
  158.         fprintf(stderr,
  159.                 "Could not open passwd file %s for reading.\n",argv[1]);
  160.         fprintf(stderr,"Use -c option to create new one.\n");
  161.         exit(1);
  162.     }
  163.     strcpy(user,argv[2]);
  164.  
  165.     found = 0;
  166.     while(!(getline(line,MAX_STRING_LEN,f))) {
  167.         if(found || (line[0] == '#') || (!line[0])) {
  168.             putline(tfp,line);
  169.             continue;
  170.         }
  171.         strcpy(l,line);
  172.         getword(w,l,':');
  173.         if(strcmp(user,w)) {
  174.             putline(tfp,line);
  175.             continue;
  176.         }
  177.         else {
  178.             printf("Changing password for user %s\n",user);
  179.             add_password(user,tfp);
  180.             found = 1;
  181.         }
  182.     }
  183.     if(!found) {
  184.         printf("Adding user %s\n",user);
  185.         add_password(user,tfp);
  186.     }
  187.     fclose(f);
  188.     fclose(tfp);
  189.     sprintf(command,"cp %s %s",tn,argv[1]);
  190.     system(command);
  191.     unlink(tn);
  192. }
  193.